MQ框架


RocketMQ

http://rocketmq.apache.org/

  1. 简介

    分布式消息中间件,阿里巴巴捐赠给 Apache 社区的开源项目 RocketMQ从Apache社区正式毕业,成为 Apache 顶级项目(TLP)

    纯Java开发

    RocketMQ 都承载着阿里巴巴生产系统 100% 的消息流转,以去年双 11 为例的, RocketMQ 完成了 1.2 万亿消息精准低延迟投递,交易峰值高达 17 万笔/秒。

    特性:

    低延迟、高并发:99.6% 以上的响应延迟在 1 毫秒以内
    面向金融:满足跟踪和审计的高可用性
    工业级适用:可确保万亿量级的消息发送
    中立性:支持多种消息传递协议,如 JMS 和 OpenMessaging
    性能可靠:给予足够的磁盘空间,消息可以累积存放而没有性能损失。
    

RabbitMQ (DXP项目用过)

https://www.cnblogs.com/luxiaoxun/p/3918054.html

  1. AMQP
  • 包括以下组件:

    1.Server(Broker): 接受客户端连接,实现消息队列和路由功能。
    
    2.Virtual Host: 类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,但是权限控制的最小粒度是Virtual Host
    
    3.Exchange: 接受生产者发送的消息,并根据Binding规则将消息路由给服务器中的队列。ExchangeType决定了Exchange路由消息的行为,例如,在RabbitMQ中,ExchangeType有direct、Fanout和Topic三种,不同类型的Exchange路由的行为是不一样的。
    
    4.Message Queue:消息队列,用于存储还未被消费者消费的消息。
    
    5.Message: 由Header和Body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、由哪个Message Queue接受、优先级是多少等。而Body是真正需要传输的APP数据。
    
    6.Binding: 联系了Exchange与Message Queue。Exchange在与多个Message Queue发生Binding后会生成一张路由表,路由表中存储着Message Queue所需消息的限制条件即Binding Key。当Exchange收到Message时会解析其Header得到Routing Key,Exchange根据Routing Key与Exchange Type将Message路由到Message Queue。Binding Key由Consumer在Binding Exchange与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定。
    
    7.Connection: 连接,对于RabbitMQ而言,其实就是一个位于客户端和Broker之间的TCP连接。
    
    8.Channel: 信道,仅仅创建了客户端到Broker之间的连接后,客户端还是不能发送消息的。需要为每一个Connection创建Channel,AMQP协议规定只有通过Channel才能执行AMQP的命令。一个Connection可以包含多个Channel。之所以需要Channel,是因为TCP连接的建立和释放都是十分昂贵的,如果一个客户端每一个线程都需要与Broker交互,如果每一个线程都建立一个TCP连接,暂且不考虑TCP连接是否浪费,就算操作系统也无法承受每秒建立如此多的TCP连接。RabbitMQ建议客户端线程之间不要共用Channel,至少要保证共用Channel的线程发送消息必须是串行的,但是建议尽量共用Connection。
    
    9.Command: AMQP的命令,客户端通过Command完成与AMQP服务器的交互来实现自身的逻辑。例如在RabbitMQ中,客户端可以通过publish命令发送消息,txSelect开启一个事务,txCommit提交一个事务。
    

image

  • AMQP协议本身包括三层:

    1.Module Layer,位于协议最高层,主要定义了一些供客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑,例如,客户端可以通过queue.declare声明一个队列,利用consume命令获取一个队列中的消息。
    
    2.Session Layer,主要负责将客户端的命令发送给服务器,在将服务器端的应答返回给客户端,主要为客户端与服务器之间通信提供可靠性、同步机制和错误处理。
    
    3.Transport Layer,主要传输二进制数据流,提供帧的处理、信道复用、错误检测和数据表示。
    

image

  1. 简介
  • 开源的AMQP(高级消息队列协议)实现
  • 服务器端用Erlang语言编写,支持多种客户端

    Erlang是一种通用的面向并发的编程语言,目的是创造一种可以应对大规模并发活动的编程语言和运行环境。

    属于多重范型编程语言,涵盖函数式、并发式及分布式。
    结构化,动态类型编程语言,内建并行计算支持。
    使用Erlang编写出的应用运行时通常由成千上万个轻量级进程组成,并通过消息传递相互通讯。
    进程间上下文切换对于Erlang来说仅仅 只是一两个环节,比起C程序的线程切换要高效得多得多了。
    Erlang运行时环境是一个虚拟机,有点像Java虚拟机,这样代码一经编译,同样可以随处运行。
    它的运行时系统甚至允许代码在不被中断 的情况下更新。
    另外如果需要更高效的话,字节代码也可以编译成本地代码运行。
    

    Erlang特性:

    ● 并发性 - Erlang支持超大量级的并发进程,并且不需要操作系统具有并发机制。
    ● 分布式 - 一个分布式Erlang系统是多个Erlang节点组成的网络(通常每个处理器被作为一个节点)
    ● 健壮性 - Erlang具有多种基本的错误检测能力,它们能够用于构建容错系统。
    ● 软实时性- Erlang支持可编程的“软”实时系统,使用了递增式垃圾收集技术。
    ● 热代码升级-Erlang允许程序代码在运行系统中被修改。旧代码能被逐步淘汰而后被新代码替换。在此过渡期间,新旧代码是共存的。
    ● 递增式代码装载-用户能够控制代码如何被装载的细节。
    ● 外部接口-Erlang进程与外部世界之间的通讯使用和在Erlang进程之间相同的消息传送机制。
    ● Fail-fast(中文译为速错),即尽可能快的暴露程序中的错误。
    ● 面向并发的编程(COP concurrency-oriented programming)
    ● 函数式编程
    ● 动态类型
    ● 及早求值或严格求值
    ● 支持脚本运行
    
  • 高可用性

  • 提供消息持久化
    *
  1. 使用场景
  • 场景1:单发送单接收
  • 场景2:单发送多接收
  • 场景3:Publish/Subscribe

    使用场景:发布、订阅模式,发送端发送广播消息,多个接收端接收。
    
  • 场景4:Routing (按路线发送接收)

    使用场景:发送端按routing key发送消息,不同的接收端按不同的routing key接收消息。
    1、exchange的type为direct
    2、发送消息的时候加入了routing key
    在绑定queue和exchange的时候使用了routing key,即从该exchange上只接收routing key指定的消息。
    
  • 场景5:Topics (按topic发送接收)

    使用场景:发送端不只按固定的routing key发送消息,而是按字符串“匹配”发送,接收端同样如此。
    1、exchange的type为topic
    2、发送消息的routing key不是固定的单词,而是匹配字符串,如"*.lu.#",*匹配一个单词,#匹配0个或多个单词。
    
  1. RabbitMQ分布式集群架构

http://blog.csdn.net/woogeyu/article/details/51119101

  1. 问题解决
  • rabbitmq堆积消息后生产速率降低的问题

https://wenku.baidu.com/view/e627a4a31eb91a37f0115c31.html

在rabbitmq没有消费者的情况下,生产者持续向mq发消息,使得消息在mq中大量堆积,发送速率不受影响,但当有新的消费者连接上mq并开始接收消息时,生产速率大幅降低。

应对措施:

    1. 打破发送循环条件。
        (1) 设置合适的qos值,当qos值被用光,而新的ack未被mq接收时,就可以跳出发送循 环,去接收新的消息。
        (2) 消息者到主动block接收进程,消费者感知到接收消息的速度过快时,主动block,利用 block与unblock方法调节接收速率。当接收进程被block时,mq跳出发送循环。
    2. 建立新的队列  若服务器cpu资源有较多剩余,而又不需要保证消息的顺序的情况下可以通过建立新的vhost,在该vhost下创建queue,生产者将消息发送掉新的queue,消费者同时订阅新旧queue。
    3. 使用缓存  在生产者端使用缓存,当生产速率受到流控限制时,缓存数据。在堆积的消息被处理完后,生产速率恢复正常时,此时将缓存的数据发送给MQ。
    4. 更新rabbitmq版本
    5. 加机器。

RabbitMQ,ActiveMq,ZeroMq比较

http://blog.csdn.net/linsongbin1/article/details/47781187

  1. TPS比较

    ZeroMq 最好,RabbitMq 次之, ActiveMq 最差

image

  1. 持久化消息比较

    ZeroMq不支持,ActiveMq和RabbitMq都支持

  2. 可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统、社区

    RabbitMq最好,ActiveMq次之,ZeroMq最差
    虽然ActiveMQ也具备,但是它性能不及RabbitMQ

  3. 高并发

    RabbitMQ最高,原因是它的实现语言是天生具备高并发高可用的erlang语言

  4. 综合来看,RabbitMQ是首选

    淘宝使用RabbitMQ的心得,可以参看一些业务场景。

    http://www.docin.com/p-462677246.html

Kafka/Jafka和RabbitMQ的比较

http://blog.csdn.net/u010233323/article/details/52103042

  • 关于Kafka/Jafka

    Jafka是在Kafka之上孵化而来的,即Kafka的一个升级版

    * 更快!单机上万TPS
    用topic来进行消息管理,每个topic包含多个part,每个part对应一个逻辑log,有多个segment组成。
    segment中的消息id由其逻辑位置决定,可以用消息id直接定位到消息的存储位置,避免id到位置的额外映射。
    生产者发到某个topic的消息会被均匀的分布到多个part上,broker收到消息会写入最后的segment文件中,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息消费者才能收到。并且通过rolling的机制,保证segment的文件不至于过大。
    消费者可以rewind back到任意位置重新进行消费,当消费者故障时,可以选择最小的offset进行重新读取消费消息。
    

    一些深坑

    Kafka对消息的重复、丢失、错误以及顺序型没有严格的要求。但是part只会被consumer group内的一个consumer消费,故kafka保证每个parti内的消息会被顺序的消费。
    broker没有副本机制,一旦broker宕机,该broker的消息将都不可用。同时broker是无状态的,broker不保存消费者的状态,由消费者自己保存。无状态导也致消息的删除成为难题,所以Kafka选择消息保存一定时间后会被删除。
    大量的依赖Zookeeper,需要Zookeeper来管理broker与consumer的动态加入与离开。以及消费关系及每个partion的消费信息。
    

    特定故障场景

    * Kafka大量依赖Zookeeper,它的broker并不保存任何状态,如果Zookeeper集群不幸悲剧了,那么整个Kafka集群的消息就全完蛋了。
    * 当一个broker当机了整个消息队列由于负载均衡的算法,在一瞬间消费者和生产者之间的消息就全乱掉了。很多需要保证消息顺序的系统一下子就完蛋了。
    
  1. RabbitMq比kafka成熟,在可用性上,稳定性上,可靠性上,RabbitMq超过kafka

    安全性和易用性都是RabbitMQ的强项

  2. Kafka设计的初衷就是处理日志的,可以看做是一个日志系统,针对性很强,所以它并没有具备一个成熟MQ应该具备的特性

  3. Kafka的性能(吞吐量、tps)比RabbitMq要强

    100k/sec性能往往是人们选择 Apache Kafka的关键驱动力

    20K/sec是很容易使用一个Rabbit队列实现的

  4. 总结

  • RabbitMQ该怎么用

    * RabbitMQ的消息应当尽可能的小,并且只用来处理实时且要高可靠性的消息。
    * 消费者和生产者的能力尽量对等,否则消息堆积会严重影响RabbitMQ的性能。
    * 集群部署,使用热备,保证消息的可靠性。
    
  • Kafka该怎么用

    * 应当有一个非常好的运维监控系统,不单单要监控Kafka本身,还要监控Zookeeper。
    * 对消息顺序不依赖,且不是那么实时的系统。
    * 对消息丢失并不那么敏感的系统。